# -- coding: utf8 --
# import inspect
import math
import datetime
import json
import jsonpath
import logging
import redis
import requests
import numpy as np
import pandas as pd
from collections import OrderedDict
from requests.adapters import HTTPAdapter
from urllib.parse import urlparse, parse_qs
from concurrent.futures import as_completed
from requests_futures.sessions import FuturesSession
from sqlalchemy import *
from geoalchemy2 import WKTElement

# from line_profiler import LineProfiler

"""
LBS工具包
使用多线程请求高德的版本
测试请求96个节点为 1087 < 单线程版本 2100
"""
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

req = requests.Session()
req.mount('http://', HTTPAdapter(max_retries=3))
req.mount('https://', HTTPAdapter(max_retries=3))


def conn_redis():
    model_redis = redis.Redis(
        host='172.16.254.164',
        port=6379,
        db=0,
        password='123456'
    )
    return model_redis


def conn_pgsql():
    # 连接数据库
    conn = create_engine('postgresql+psycopg2://postgres:postgres@172.16.254.164/postgres',
                         connect_args={'connect_timeout': 3},
                         max_overflow=0,  # 超出连接池数量不增加线程
                         pool_size=20,  # 连接池大小
                         pool_timeout=30,  # 连接超时时间
                         pool_recycle=-1,  # 是否回收连接
                         pool_pre_ping=True  # 是否ping连接（断线重连）
                         )
    # Session = sessionmaker(bind=conn)
    # session = Session()
    logger.debug('connect pgsql')
    return conn


# lbs服务商信息
lbs_service = {
    'amap':
        {
            'key': 'xxxxxxxxxxxxxx', 'key_name': 'key',
            'url': 'https://restapi.amap.com/v3/', 'parameters': '',
            'status': '$.status', 'status_value': 1, 'info': '$.info',
            'location': {'url': 'geocode/geo', 'result': ['$.geocodes[*].location']},
            'time': {'url': 'direction/transit/integrated',
                     'result': ['$.route.distance', '$.route.transits[*].duration', '$.route.transits[*].distance']},
            'district': {'url': 'config/district', 'key': 'keywords', 'result': ['$.districts[*].center']},
            'batch': {'url': 'batch', 'ops': 'ops'}
        },
    'baidu':
        {
            'key': 'xxxxxxxxxxxxxx', 'key_name': 'ak',
            'url': 'http://api.map.baidu.com/', 'parameters': '&output=json',
            'status': '$.status', 'status_value': 0, 'info': '$.message',
            'location': {'url': 'geocoding/v3/', 'result': ['$.result.location.lng', '$.result.location.lat']},
            'time': {'url': 'directionlite/v1/transit',
                     'result': ['$.route.distance', '$.result.routes[*].duration', '$.result.routes[*].distance']},
            'district': {'url': 'place/v2/search', 'key': 'query',
                         'result': ['$.result.location.lng', '$.result.location.lat']},
            'batch': {'url': 'batch', 'ops': 'ops'}
        }
}

default_service = 'amap'
default_key = 'ccf8ca65aafe9bcdff8287744a321da7'
amap_keys = ['ccf8ca65aafe9bcdff8287744a321da7', 'a1f4a6080cbbbf3f4a55364315019133', 'bd96d1cd5ee1529331801203631071c7',
             '7e65568893ad41c04cc3656e4e2cba77', '8b71ccb82bdb84c4f33f42f7f41a1637']
dtype_dic = {'id': str, 'city_code': str}
try:
    df_cities = pd.read_csv('/root/python/disp/data/city.csv', dtype=dtype_dic)
    # df_cities = pd.read_csv('../data/city.csv', dtype=dtype_dic)
except:
    df_cities = None


def get_yesterday(day_num=1, day_format="%Y-%m-%d"):
    today = datetime.date.today()
    oneday = datetime.timedelta(days=day_num)
    yesterday = today - oneday
    return yesterday.strftime(day_format)


def change_lbs(call_func):
    global default_service
    if default_service == 'amap':
        default_service = 'baidu'
    # return call_func(*args)
    print('when call %s the amap is used out, please change baidu' % call_func)


def dict_to_parameters(dic):
    ret_str = "&".join([str(k) + "=" + str(v) for k, v in dic.items()])
    return ret_str


def get_api(func_name, req_dict, ret_paths):
    """
    API接口get查询
    注意发送参数格式为普通参数，并非json
    :param func_name:
    :param req_dict:
    :param ret_paths:
    :return:
    """
    global lbs_service, default_service, default_key, amap_keys, req
    url = lbs_service[default_service]['url'] + func_name + '?'
    req_dict[lbs_service[default_service]['key_name']] = default_key
    req_data = dict_to_parameters(req_dict)
    req_data += lbs_service[default_service]['parameters']
    # print(req_data)
    status = None
    info = None
    retry = 0
    ret_value = None
    while status != lbs_service[default_service]['status_value'] and retry < 3:
        try:
            response = req.get(url + req_data, timeout=1)
            resp_json = json.loads(response.text)
        except Exception as e:
            logger.exception(e)
            resp_json = None
        if resp_json is not None:
            status = int(jsonpath.jsonpath(resp_json, lbs_service[default_service]['status'])[0])
            info = jsonpath.jsonpath(resp_json, lbs_service[default_service]['info'])[0]
            ret_values = [jsonpath.jsonpath(resp_json, ret_path) for ret_path in ret_paths]
            ret_value = [ret for ret in ret_values if ret]
            if len(ret_value) == 0:
                ret_value = None
            # print(resp_json)
        if status != lbs_service[default_service]['status_value']:
            if info == 'DAILY_QUERY_OVER_LIMIT':
                logger.debug('quota used out, change next key.')
                amap_keys.remove(default_key)
                if len(amap_keys) > 0:
                    # 更换到下一个key
                    default_key = amap_keys[0]
                    req_dict[lbs_service[default_service]['key_name']] = default_key
                    req_data = dict_to_parameters(req_dict)
                    req_data += lbs_service[default_service]['parameters']
                # change_lbs(inspect.stack()[1].function)
                # break
            retry += 1
            logger.debug('retry:' + str(retry))
            # time.sleep(1)
    if retry == 3:
        logger.debug(req_data)
        logger.debug(resp_json)
    return ret_value


def post_api(func_name, req_dict, ret_paths):
    """
    API接口post查询
    :param func_name:
    :param req_dict:
    :param ret_paths:
    :return:
    """
    global lbs_service, default_service, default_key, amap_keys
    url = lbs_service[default_service]['url'] + func_name + '?'
    url += lbs_service[default_service]['key_name'] + '=' + default_key
    url += lbs_service[default_service]['parameters']
    headers = {'content-type': 'application/json'}
    # logger.debug('request dict:' + str(req_dict))
    # 高德1批最多20个,一次装载20个
    workers = math.ceil(len(req_dict) / 20)
    if workers < 1:
        workers = 1
    ret_value = []
    result_values = []
    with FuturesSession(max_workers=workers) as session:
        # post_data = json.dumps(req_dict[0: 20])
        futures = [
            session.post(url + '&i=' + str(i), json.dumps({"ops": req_dict[20 * i: 20 * (i + 1)]}, ensure_ascii=True),
                         headers=headers) for i in range(workers)]
        for future in as_completed(futures):
            try:
                response = future.result()
                # logger.debug(response.request.body)
                parsed = urlparse(response.url)
                index = parse_qs(parsed.query)['i'][0]
                resp_jsons = response.json()
            except Exception as e:
                logger.exception(e)
                resp_jsons = None
            if resp_jsons is not None:
                if 'status' in resp_jsons and resp_jsons['status'] == '0':
                    logger.debug("response: " + str(resp_jsons))
                    return {'i': index, 'ret': resp_jsons['info']}
                for r_json in resp_jsons:
                    # logger.debug('return json:' + str(r_json))
                    if 'status' in r_json and r_json['status'] == 200:
                        resp_json = r_json['body']
                        # logger.debug(resp_json)
                        stat = int(jsonpath.jsonpath(resp_json, lbs_service[default_service]['status'])[0])
                        info = jsonpath.jsonpath(resp_json, lbs_service[default_service]['info'])[0]
                        r_value = {'i': index,
                                   'ret': [jsonpath.jsonpath(resp_json, ret_path) for ret_path in ret_paths]}
                        # r_value = [ret for ret in r_values if ret]
                        if stat != lbs_service[default_service]['status_value'] or len(r_value) == 0:
                            if info == 'DAILY_QUERY_OVER_LIMIT':
                                logger.debug('quota used out, change next key.')
                                amap_keys.remove(default_key)
                                if len(amap_keys) > 0:
                                    # 更换到下一个key
                                    default_key = amap_keys[0]
                                    # 由于while循环在外层方法，更换key后直接退出，避免无谓尝试
                                    break
                            r_value = {'i': index, 'ret': [None] * len(ret_paths)}
                        # logger.debug('json result:' + str(r_value))
                        ret_value.append(r_value)
    if len(ret_value) > 0:
        ret_value = sorted(ret_value, key=lambda k: k['i'])
        result_values = [r['ret'] for r in ret_value]
    return result_values


def get_city_value(city_id, code=True):
    global df_cities, default_service
    city_value = ''
    df_city = df_cities[df_cities['id'] == str(city_id)].reset_index(drop=True)
    if len(df_city) > 0:
        city = df_city.loc[0]
        if default_service == 'amap' and code:
            city_value = str(city['city_code'])
        else:
            city_value = str(city['city_name'])
    # logger.debug('search city id:' + str(city_id) + ', get city value:' + str(city_value))
    return city_value


def get_city_prop(city_code, prop_name='id'):
    df_city = df_cities[df_cities['city_code'] == str(city_code)].reset_index(drop=True)
    if len(df_city) > 0:
        city_one = df_city.loc[0]
        city_prop = str(city_one[prop_name])
    else:
        city_prop = None
    return city_prop


def get_city_code(city_value, search_col='id', result_col='city_code'):
    df_city = df_cities[df_cities[search_col] == str(city_value)].reset_index(drop=True)
    if len(df_city) > 0:
        city_one = df_city.loc[0]
        city_prop = str(city_one[result_col])
    else:
        city_prop = None
    return city_prop


def _haversine(lon1, lat1, lon2, lat2):
    """
    经纬度坐标间距离 https://en.wikipedia.org/wiki/Haversine_formula
    Args:
        lon1: longitude of pt 1,
        lat1: latitude of pt 1,
        lon2: longitude of pt 2,
        lat2: latitude of pt 2
    Returns:
        the distace in km between pt1 and pt2
    """
    # convert decimal degrees to radians
    lon1, lat1, lon2, lat2 = map(np.radians, [lon1, lat1, lon2, lat2])
    # haversine formula
    dlon = lon2 - lon1
    dlat = lat2 - lat1
    a = (np.sin(dlat / 2) ** 2 +
         np.cos(lat1) * np.cos(lat2) * np.sin(dlon / 2) ** 2)
    c = 2 * np.arcsin(np.sqrt(a))
    # 6367 km is the radius of the Earth
    km = 6367 * c
    return km


def get_distance(order1, order2):
    distance = _haversine(order1['lon'], order1['lat'], order2['lon'], order2['lat'])
    return distance


def baidu2amap(lon, lat):
    """
    百度坐标转高德坐标
    :param lon:
    :param lat:
    :return:
    """
    PI = 3.14159265358979324 * 3000.0 / 180.0
    x = lon - 0.0065
    y = lat - 0.006
    z = math.sqrt(x * x + y * y) - 0.00002 * math.sin(y * PI)
    theta = math.atan2(y, x) - 0.000003 * math.cos(x * PI)
    lon = z * math.cos(theta)
    lat = z * math.sin(theta)
    return str(lon) + ',' + str(lat)


# //百度坐标转高德（传入经度、纬度）
# function bgps_gps(bd_lng, bd_lat) {
#     var X_PI = Math.PI * 3000.0 / 180.0;
#     var x = bd_lng - 0.0065;
#     var y = bd_lat - 0.006;
#     var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * X_PI);
#     var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * X_PI);
#     var gg_lng = z * Math.cos(theta);
#     var gg_lat = z * Math.sin(theta);
#     return {lng: gg_lng, lat: gg_lat}
# }
# //高德坐标转百度（传入经度、纬度）
# function gps_bgps(gg_lng, gg_lat) {
#     var X_PI = Math.PI * 3000.0 / 180.0;
#     var x = gg_lng, y = gg_lat;
#     var z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * X_PI);
#     var theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * X_PI);
#     var bd_lng = z * Math.cos(theta) + 0.0065;
#     var bd_lat = z * Math.sin(theta) + 0.006;
#     return {
#         bd_lat: bd_lat,
#         bd_lng: bd_lng
#     };
# }


def get_district(keywords):
    """
    行政区域查询
    :param keywords:
    :return:
    """
    district = None
    req_dict = {lbs_service[default_service]['district']['key']: keywords}
    if default_service == 'baidu':
        req_dict['region'] = keywords
    results = get_api(lbs_service[default_service]['district']['url'], req_dict,
                      lbs_service[default_service]['district']['result'])
    if results is not None:
        try:
            if default_service == 'amap':
                district = str(results[0][0])
            else:
                district = baidu2amap(results[0][0], results[1][0])
        except:
            print(results)
    return district


def check_location(city_id, lon, lat):
    """
    检查经纬度与城市是否一致
    :param city_id:
    :param lon:
    :param lat:
    :return:
    """
    in_city = True
    city_name = get_city_value(city_id, False)
    locations = get_district(city_name)
    try:
        lonlat1 = locations.split(',')
        lon1 = lonlat1[0]
        lat1 = lonlat1[1]
    except:
        lon1 = None
        lat1 = None
        print(locations)
    distance = _haversine(lon, lat, lon1, lat1)
    if distance >= 100:
        in_city = False
    return in_city


def geo_to_location(address, city_id=None, city_name=None):
    """
    地理位置转经纬度
    :param address:
    :param city_id:
    :param city_name:
    :return:
    """
    global lbs_service, default_service
    locations = None
    req_dict = {'address': address}
    if city_id is not None:
        city_value = get_city_value(city_id, False)
        req_dict['city'] = city_value
    if city_name is not None:
        req_dict['city'] = city_name
    results = get_api(lbs_service[default_service]['location']['url'], req_dict,
                      lbs_service[default_service]['location']['result'])
    if results is not None:
        try:
            if default_service == 'amap':
                locations = str(results[0][0])
            else:
                locations = baidu2amap(results[0][0], results[1][0])
        except:
            logger.debug(results)
    return locations


def get_start_hour(reserve_tm):
    """
    取得出发时间
    :param reserve_tm: 预约时间
    :return:
    """
    reserve_time = datetime.datetime.strptime(reserve_tm, '%Y-%m-%d %H:%M:%S')
    start_time = reserve_time - datetime.timedelta(hours=1)
    start_hour = str(start_time.hour) + ":00"
    return start_hour


def city_location_to_time(point1, point2, city_name1, start_time, city_name2):
    """
    经纬度位置预测到达时间:默认使用公交方式
    :param point1:
    :param point2:
    :param city_name1:
    :param start_time:
    :param city_name2:
    :return:
    """
    global lbs_service, default_service
    ret_time = None
    ret_distance = None
    if default_service == 'baidu':
        try:
            points = point1.split(',')
            point1 = points[1] + ',' + points[0]
            points = point2.split(',')
            point2 = points[1] + ',' + points[0]
        except:
            logger.debug(point1 + ' ' + point2)
    req_dict = {'origin': point1, 'destination': point2, 'city': city_name1}
    if default_service == 'amap':
        req_dict['cityd'] = city_name2
        req_dict['time'] = start_time
    results = get_api(lbs_service[default_service]['time']['url'], req_dict,
                      lbs_service[default_service]['time']['result'])
    if results is not None:
        try:
            ret_time = int(results[0][0])
            ret_distance = int(results[1][0])
        except:
            logger.debug(results)
    if ret_time is None:
        ret_distance = get_position_distance(point1, point2)
        ret_time = (ret_distance / 5) * 60 * 60
    return ret_time, ret_distance


def location_to_time(point1, point2, city_id1, start_time, city_id2=None):
    """
    经纬度位置预测到达时间:默认使用公交方式
    :param point1:
    :param point2:
    :param city_id1:
    :param start_time:
    :param city_id2:
    :return:
    """
    city_value1 = get_city_value(city_id1, False)
    if city_id2 is None:
        city_value2 = city_value1
    else:
        city_value2 = get_city_value(city_id2, False)
    ret_time, ret_distance = city_location_to_time(point1, point2, city_value1, start_time, city_value2)
    return ret_time, ret_distance


def position_to_points(position):
    try:
        lon_lats = position.split(',')
        lon = round(float(lon_lats[0]), 3)
        lat = round(float(lon_lats[1]), 3)
    except Exception as e:
        logger.exception(e)
        lon = 0
        lat = 0
    # lon, lat = zip(*[(p.split(' ')[0], p.split(' ')[1]) for p in points])
    return lon, lat


def get_position_distance(origin, destination):
    p1_lon, p1_lat = position_to_points(origin)
    p2_lon, p2_lat = position_to_points(destination)
    if p1_lon > 0 and p1_lat > 0 and p2_lon > 0 and p2_lat > 0:
        distance = math.ceil(_haversine(p1_lon, p1_lat, p2_lon, p2_lat) * 1000)
    else:
        distance = 0
    return distance


def batch_transit_time(no_exists_dicts):
    """
    批量获取路程时间(仅限高德)
    :param no_exists_dicts:
    :return:
    """
    global lbs_service, default_service, default_key
    result = []
    fail_list = no_exists_dicts.copy()
    retry = 0
    logger.debug('batch ops total:' + str(len(fail_list)))
    while len(fail_list) > 0 and retry < 3:
        prev_fail = len(fail_list)
        no_exists_dict = fail_list.copy()
        logger.debug("fail_list: " + str(len(fail_list)))
        # batch_ops = [{'origin': p1, 'destination': p2, 'city': city1, 'cityd': city2, 'time': start_time} for p1 in p1_batch]
        batch_ops = [{"url": "/v3/" + lbs_service[default_service]['time']['url'] + "?" + lbs_service[default_service][
            'key_name'] + "=" + default_key + "&" + dict_to_parameters(ops)} for ops in
                     no_exists_dict]
        # print('load batch:' + str(len(batch_ops)))
        # req_dict = {"ops": batch_ops}
        results = post_api(lbs_service[default_service]['batch']['url'], batch_ops,
                           lbs_service[default_service]['time']['result'])
        if results is not None:
            logger.debug("post results:" + str(len(results)))
            # logger.debug(results)
            for i, r in enumerate(results):
                travel_time = -1
                distance = -1
                if len(r) > 1:
                    try:
                        travel_time = int(r[1][0])
                        distance = int(r[2][0])
                    except Exception as e:
                        logger.exception(e)
                        # logger.debug("no_exists_dict[" + str(i) + "]:" + str(no_exists_dict[i]))
                elif len(r) == 1:
                    # 高德未反馈路线规划方案的情况
                    logger.debug("distance: " + str(r[0][0]))
                    try:
                        distance = int(r[0][0])
                    except Exception as e:
                        logger.exception(e)
                if distance <= 0:
                    distance = get_position_distance(no_exists_dict[i]['origin'], no_exists_dict[i]['destination'])
                # 如果距离太近则返回1秒，否则返回2小时
                if travel_time <= 0:
                    if distance <= 1000:
                        travel_time = 1
                    else:
                        travel_time = 2 * 60 * 60
                ret = {'p1': no_exists_dict[i]['origin'],
                       'p2': no_exists_dict[i]['destination'],
                       'start': no_exists_dict[i]['time'],
                       'travel_type': no_exists_dict[i]['travel_type'],
                       'period': no_exists_dict[i]['period'],
                       'travel_time': travel_time,
                       'distance': distance}
                result.append(ret)
                fail_list.remove(no_exists_dict[i])
        # 只要有成功的子查询，就不能算作重试次数
        if len(fail_list) == prev_fail:
            retry += 1
            logger.debug('retry: ' + str(retry))
    return result


def batch_location_to_time(p1_list, p2, city_id1, start_time, travel_type='bus', city_id2=None):
    """
    批量获取路程时间(仅限高德)
    :param p1_list:
    :param p2:
    :param city_id1:
    :param start_time:
    :param travel_type: 默认使用公交
    :param city_id2:
    :return:
    """
    city1 = get_city_value(city_id1)
    if city_id2 is None:
        city2 = city1
    else:
        city2 = get_city_value(city_id2)
    not_exists_dict = [
        {'origin': p1, 'destination': p2, 'city': city1, 'cityd': city2, 'time': start_time, 'travel_type': travel_type}
        for p1 in p1_list]
    return batch_transit_time(not_exists_dict)


def create_wkt_element(geom):
    return WKTElement(geom.wkt)


def get_inventory(artisan_id, df_inventory):
    """
    取得时间库存
    :param artisan_id:
    :return:
    """
    inventory = None
    artisan_inventory = df_inventory[df_inventory['artisan_id'] == artisan_id]
    if artisan_inventory is not None:
        inventory = list(artisan_inventory.iloc[0][1:])
    return inventory


def get_prev_point(invent, stop_values):
    forward_points = []
    for stop in stop_values:
        try:
            forward_index = invent[::-1].index(stop)
        except:
            forward_index = 0
        forward_points.append(forward_index)
    return min(forward_points)


def get_next_point(invent, stop_values):
    backward_points = []
    for stop in stop_values:
        try:
            backward_index = invent.index(stop)
        except:
            backward_index = len(invent)
        backward_points.append(backward_index)
    return min(backward_points)


def get_start_index(genes_range):
    """
    取得基因片段的起始索引位置
    :param genes_range:
    :return:
    """
    try:
        time_start = len(genes_range) - genes_range[::-1].index(0)
    except:
        time_start = 0
    try:
        time_close = len(genes_range) - genes_range[::-1].index(-1)
    except:
        time_close = 0
    start_index = max(time_start, time_close)
    return start_index


def get_end_index(genes_range):
    """
    取得基因片段的结束索引位置
    :param genes_range:
    :return:
    """
    try:
        time_end = genes_range.index(0)
    except:
        time_end = len(genes_range)
    try:
        time_close = genes_range.index(-1)
    except:
        time_close = len(genes_range)
    end_index = min(time_end, time_close)
    return end_index


def get_order_interval(plans, order1=None, order2=None):
    """
    取得订单间隙
    :param plans:
    :param order1:
    :param order2:
    :return:
    """
    if order1 is not None:
        o_start_index = len(plans) - plans[::-1].index(order1)
    else:
        o_start_index = 0
    if order2 is not None:
        o_end_index = plans.index(order2)
    else:
        o_end_index = len(plans)
    logger.debug("o_start_index:" + str(o_start_index) + ", o_end_index:" + str(o_end_index))
    return o_start_index, o_end_index


def get_lock_travel_num(inventory, genes):
    """
    取得路程锁定时间
    :param inventory:
    :param genes:
    :return: 锁定路程时间单位个数
    """
    orders = list(get_genes_order(genes))
    plans = genes[1:]
    order_lock_time = {}
    logger.debug(orders)
    for i, o in enumerate(orders):
        if i > 0:
            order_prev = orders[i-1]
        else:
            order_prev = None
        o_start_index, o_end_index = get_order_interval(plans, order_prev, o)
        order_range = plans[o_start_index: o_end_index]
        order_index = get_start_index(order_range)
        lock_range = inventory[o_start_index: o_end_index]
        lock_index = get_start_index(lock_range)
        # logger.debug(order_range)
        # logger.debug(lock_range)
        # logger.debug("order_index:" + str(order_index) + ", lock_index:" + str(lock_index))
        order_lock_time[o] = order_index - lock_index
    return order_lock_time


def get_genes_order(ind):
    """
    取得个体对应的订单
    :param ind:
    :return:
    """
    order_list = OrderedDict.fromkeys(i for i in ind[1:] if i > 0).keys()
    # logger.debug(order_list)
    return order_list


def get_lock_delay_num(inventory, genes):
    """
    取得订单完成后的缓冲时间
    :param inventory:
    :param genes:
    :return: 锁定缓冲时间单位个数
    """
    orders = list(get_genes_order(genes))
    plans = genes[1:]
    order_delay_time = {}
    for i, o in enumerate(orders):
        try:
            order_next = orders[i+1]
        except:
            order_next = None
        o_start_index, o_end_index = get_order_interval(plans, o, order_next)
        order_range = plans[o_start_index: o_end_index]
        order_length = get_end_index(order_range)
        lock_range = inventory[o_start_index: o_end_index]
        lock_length = get_end_index(lock_range)
        # logger.debug(order_range)
        # logger.debug(lock_range)
        # logger.debug("order_length:" + str(order_length) + ", lock_length:" + str(lock_length))
        order_delay_time[o] = lock_length - order_length
    return order_delay_time


if __name__ == '__main__':
    default_service = 'amap'
    # default_service = 'baidu'
    city_id = '2'
    # address='朝阳区三元桥时间国际'
    # location = geo_to_location(address, city_id)
    # print(location)
    p1 = '116.481,39.989'
    p2 = '116.434,39.908'
    t_start_time = '10:00'
    # 测试单个查询
    # ret1, ret2 = location_to_time(p1, p2, city_id, t_start_time)
    # print(ret1)
    # print(ret2)
    # 测试批量查询
    no_exists_dicts = [
        {'origin': '116.393,39.966', 'destination': '116.397,39.855', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.394,39.966', 'destination': '116.396,39.855', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.393,39.965', 'destination': '116.397,39.855', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.394,39.965', 'destination': '116.396,39.855', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.393,39.966', 'destination': '116.397,39.854', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.394,39.966', 'destination': '116.396,39.854', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.393,39.965', 'destination': '116.397,39.854', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.394,39.965', 'destination': '116.396,39.854', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.393,39.966', 'destination': '116.397,39.853', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.394,39.966', 'destination': '116.396,39.853', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.393,39.965', 'destination': '116.397,39.853', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.394,39.965', 'destination': '116.396,39.853', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.393,39.966', 'destination': '116.397,39.852', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.394,39.966', 'destination': '116.396,39.852', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.393,39.965', 'destination': '116.397,39.852', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.394,39.965', 'destination': '116.396,39.852', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.393,39.966', 'destination': '116.397,39.845', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.394,39.966', 'destination': '116.396,39.845', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.393,39.965', 'destination': '116.397,39.845', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.394,39.965', 'destination': '116.396,39.845', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.393,39.966', 'destination': '116.397,39.844', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.394,39.966', 'destination': '116.396,39.844', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.393,39.965', 'destination': '116.397,39.844', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.394,39.965', 'destination': '116.396,39.844', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.393,39.966', 'destination': '116.397,39.843', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.394,39.966', 'destination': '116.396,39.843', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.393,39.965', 'destination': '116.397,39.843', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.394,39.965', 'destination': '116.396,39.843', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.393,39.966', 'destination': '116.397,39.842', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.394,39.966', 'destination': '116.396,39.842', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.393,39.965', 'destination': '116.397,39.842', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.384,39.965', 'destination': '116.396,39.842', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.383,39.966', 'destination': '116.397,39.855', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.384,39.966', 'destination': '116.396,39.855', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.383,39.965', 'destination': '116.397,39.855', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.384,39.965', 'destination': '116.396,39.855', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.383,39.966', 'destination': '116.397,39.854', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.384,39.966', 'destination': '116.396,39.854', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 0},
        {'origin': '116.383,39.965', 'destination': '116.397,39.854', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 1},
        {'origin': '116.384,39.965', 'destination': '116.396,39.854', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 1},
        {'origin': '116.383,39.966', 'destination': '116.397,39.853', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 1},
        {'origin': '116.384,39.966', 'destination': '116.396,39.853', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 1},
        {'origin': '116.383,39.965', 'destination': '116.397,39.853', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 1},
        {'origin': '116.384,39.965', 'destination': '116.396,39.853', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 1},
        {'origin': '116.383,39.966', 'destination': '116.397,39.852', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 1},
        {'origin': '116.384,39.966', 'destination': '116.396,39.852', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 1},
        {'origin': '116.383,39.965', 'destination': '116.397,39.852', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 1},
        {'origin': '116.384,39.965', 'destination': '116.396,39.852', 'city': '北京市', 'cityd': '北京市', 'time': 13,
         'travel_type': 'bus', 'period': 1}
    ]
    results = batch_transit_time(no_exists_dicts)
    print(results)

    # lp = LineProfiler()
    # lp.add_function(post_api)
    # lp_wrapper = lp(batch_transit_time)
    # lp_wrapper(no_exists_dicts)
    # lp.print_stats()
    # result = baidu2amap(113.325723, 23.126222)
    # result = baidu2amap(113.322845, 23.127510)
    # print(result)
